#include <kernel.h>
#include <malloc.h>
#include <string.h>
#include <csp_debug.h>
#include <csp_macros.h>
#include <csp_protocol_msg.h>
#include <kdma.h>
#include <syscall.h>





/* This function initiates the execution of a process.
 * It setup up the stackpointer according to the ABI and 
 * jump to the entry-point of the process-code.
 */
void run_process(spu_pcb_t *pcb, qword *kernel_stackpointer, syscall_pointers_t *syscalls) 
{
	uint32_t avail_stack;
	uint32_t * _sp;
	qword process_stackpointer;

	_sp = (uint32_t *) &process_stackpointer;

	avail_stack = pcb->process_data.stack_start - (
			pcb->process_data.vaddr +
			pcb->process_data.exec_size +
			pcb->process_data.bss_size);

	_sp[0] = pcb->process_data.stack_start;
	/* HACK: word 1 of SP is off by 1KB? ABI provides no answer. 
	 * It could be the memory-guard? */
	_sp[1] = avail_stack - 4*256; 
	_sp[2] = pcb->process_data.stack_start;
	_sp[3] = pcb->process_data.stack_start;

	void (*init_program)(qword k_sp, qword p_sp, void* syscalls) = 
		(void *) pcb->process_data.entry;

	/* We never return from here. */
	init_program(*kernel_stackpointer , process_stackpointer, syscalls);
}


